/**
 * 执行Ajax请求的通用函数
 * 带一个参数，是包含一系列选项的对象
 * */

function ajax(options) {
    // 如果用户没有提供某个选项的值，就用默认值替代
    options = {
        // 请求的类型
        type: options.type || "POST",
        url: options.url || "",
        timeout: options.timeout || 5000,
        // 请求失败、成功和完成（不管成功还是失败都会调用的）时执行的函数
        onComplete: options.onComplete || function () {},
        onError: options.onError || function () {},
        onSuccess: options.onSuccess || function () {},
        data: options.data || ""
    };
    // 创建请求对象
    var xml = new XMLHttpRequest();
    // 初始化异步请求
    xml.open(options.type,options.url,true);
    // 超过5秒放弃
    var timeoutLength = options.timeout;
    // 记录请求是否成功完成
    var requestDone = false;
    // 初始化一个5秒后执行的回调函数，用于取消请求（如果尚未完成的话）
    setTimeout(function () {
        requestDone =true;
    },timeoutLength);
    // 监听文档状态的更新
    xml.onreadystatechange = function () {
        // 保持等待，直到数据完全加载，并保证请求并未超时
        if(xml.readyState == 4 && !requestDone){
            // 检查是否请求成功
            if(httpSuccess(xml)){
                // 以服务器返回的数据作为调用成功回调函数
                options.onSuccess(httpData(xml,options.type));
            }else{
                options.onError();
            }
            // 调用回调函数
            options.onComplete();
            xml=null;
        }
    };
    xml.send();
    // 判断http响应是否成功
    function httpSuccess(r) {
        try {
            return !r.status && location.protocol == "file:" || (r.status >= 200 && r.status < 300) || r.status == 304 || navigator.userAgent.indexOf("Safari") >=0 && typeof r.status == "undefined";
        }catch (e) {}
        return false;
    }
    
    function httpData(r,type) {
        var ct = r.getResponseHeader("content-type");
        var data = !type && ct & ct.indexOf("xml")>=0;
        data = type == "xml" || data?r.responseXML:r.responseText;
        if(type=="script"){
            eval.call(window,data);
        }
        return data;
    }
}